package handler

import (
	"gitee.com/thewalkers/refactoring-code/model"
	"gitee.com/thewalkers/refactoring-code/settings"
	"github.com/gin-gonic/gin"
)

// Handler struct holds required services for handler to function
type Handler struct {
	EmployeeService                           model.EmployeeService
	PaycheckService                           model.PaycheckService
	PaymentClassificationService              model.PaymentClassificationService
	PaymentMethodService                      model.PaymentMethodService
	PaymentScheduleService                    model.PaymentScheduleService
	AddEmployeeTransActionService             model.AddEmployeeTransActionService
	AddCommissionedEmployeeTransactionService model.AddCommissionedEmployeeTransactionService
	AddHourlyEmployeeTransactionService       model.AddHourlyEmployeeTransactionService
	AddSalaryEmployeeTransactionService       model.AddSalaryEmployeeTransactionService
	CommissionedClassificationService         model.CommissionedClassificationService
	ChangeHourlyTransactionService            model.ChangeHourlyTransactionService
	ChangeSalariedTransactionService          model.ChangeSalariedTransactionService
	DirectMethodService                       model.DirectMethodService
	MailMethodService                         model.MailMethodService
}

// Config will hold services that will eventually injected to this
// handler layer on handler initialization
type Config struct {
	R                                         *gin.Engine
	EmployeeService                           model.EmployeeService
	PaycheckService                           model.PaycheckService
	PaymentClassificationService              model.PaymentClassificationService
	PaymentMethodService                      model.PaymentMethodService
	PaymentScheduleService                    model.PaymentScheduleService
	AddEmployeeTransActionService             model.AddEmployeeTransActionService
	AddCommissionedEmployeeTransactionService model.AddCommissionedEmployeeTransactionService
	AddHourlyEmployeeTransactionService       model.AddHourlyEmployeeTransactionService
	AddSalaryEmployeeTransactionService       model.AddSalaryEmployeeTransactionService
	CommissionedClassificationService         model.CommissionedClassificationService
	ChangeHourlyTransactionService            model.ChangeHourlyTransactionService
	ChangeSalariedTransactionService          model.ChangeSalariedTransactionService
	DirectMethodService                       model.DirectMethodService
	MailMethodService                         model.MailMethodService
}

// NewHandler initializes the handler with required injected services along with http routes
// Docs does not return as it deals directly with a reference to the gin Engine
func NewHandler(c *Config) {
	h := &Handler{
		EmployeeService:                           c.EmployeeService,
		PaycheckService:                           c.PaycheckService,
		PaymentClassificationService:              c.PaymentClassificationService,
		PaymentMethodService:                      c.PaymentMethodService,
		PaymentScheduleService:                    c.PaymentScheduleService,
		AddEmployeeTransActionService:             c.AddEmployeeTransActionService,
		AddCommissionedEmployeeTransactionService: c.AddCommissionedEmployeeTransactionService,
		AddHourlyEmployeeTransactionService:       c.AddHourlyEmployeeTransactionService,
		AddSalaryEmployeeTransactionService:       c.AddSalaryEmployeeTransactionService,
		CommissionedClassificationService:         c.CommissionedClassificationService,
		ChangeHourlyTransactionService:            c.ChangeHourlyTransactionService,
		ChangeSalariedTransactionService:          c.ChangeSalariedTransactionService,
		DirectMethodService:                       c.DirectMethodService,
		MailMethodService:                         c.MailMethodService,
	}

	g := c.R.Group(settings.Config.BaseUrl)

	// about employee
	g.POST("/employee", h.CreateEmployee)
	g.GET("/employee/:id", h.GetEmployeeByID)
	g.PUT("/employee", h.UpdateEmployee)
	g.PUT("/change_address", h.ChangeAddressTransaction)
	g.PUT("/change_name", h.ChangeNameTransaction)

	// about paycheck
	g.POST("/paycheck", h.CreatePayment)
	g.PUT("/paycheck", h.UpdatePaycheck)

	// about add employee transaction
	g.POST("/add_employee", h.AddEmployeeTransAction)
	g.POST("/add_commissioned_employee", h.AddCommissionedEmployee)
	g.POST("/add_hourly_employee", h.AddHourlyEmployee)
	g.POST("/add_salary_employee", h.AddSalariedEmployee)

	// about classification
	g.PUT("/commissioned_classification", h.ChangeCommissionedTransaction)
	g.PUT("/hourly_classification", h.ChangeHourlyTransaction)
	g.PUT("/salaried_classification", h.ChangeSalariedTransaction)

	// about payment method
	g.POST("/create_mail_method", h.AddMailMathodTransaction)
	g.POST("/create_direct_method", h.AddDirectMathodTransaction)
	g.PUT("/change_mail_method", h.ChangeMailMathodTransaction)
	g.PUT("/change_direct_method", h.ChangeDirectMathodTransaction)
}
